package com.gopay.common.trace.support;

import com.gopay.common.trace.def.Span;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * 日志上下文
 * @author ddh02
 * @LogContext
 * @2017/4/4 15:34  www.gopay.com.cn Inc.All rights reserved.
 */


public class LogContext {

    private static LogContext logContext = null;

    /**线程中存储的tid**/
    private ThreadLocal<String> tidTreadLocal = new ThreadLocal<>();

    /**当前线程存储的span对象**/
    //@Deprecated
    //private ThreadLocal<Span> nowSpanThreadLocal = new ThreadLocal<>();


    /** 本地线程计数 **/
    private ThreadLocal<Integer> countThread = new ThreadLocal<>();

    /** 用来存储当前线程的所有span  key为计数器的值 **/
    private ThreadLocal<Map<Integer, Span>> spanMap = new ThreadLocal<>();


    private LogContext() {
    }

    public static LogContext getContext() {
        if (logContext == null) {
            synchronized (LogContext.class) {
                if (logContext == null) {
                    logContext = new LogContext();
                }
            }
        }
        return logContext;
    }


    /**
     * 清空本地线程资源
     */
    public void clearThreadLocal() {
        removeTid();
        removeCount();
        removeSpanMap();
    }

    public void removeSpanMap() {
        spanMap.remove();
    }

    public Span getSpan(int count) {

        Map<Integer, Span> map = spanMap.get();

        if (map != null) {
            return map.get(count);
        }

        return null;
    }

    public void setSpan(int count, Span span) {
        Map<Integer, Span> map = spanMap.get();
        if (map == null) {
            map = new HashMap();
        }
        map.put(count, span);
        spanMap.set(map);
    }


    public Integer getCount() {
        return countThread.get();
    }

    public void setCount(Integer count) {
        countThread.set(count);
    }

    public Integer incrCount() {
        Integer count = getCount();
        if (count == null) {
            count = 0;
        }
        ++count;
        setCount(count);
        return getCount();
    }

    public Integer dncrCount() {
        Integer count = getCount();
        if (count == null) {
            count = 0;
        }
        --count;
        setCount(count);
        return getCount();
    }

    public void removeCount() {
        countThread.remove();
    }

    public String getTid() {
        return tidTreadLocal.get();
    }

    public void setTid(String tid) {
        tidTreadLocal.set(tid);
    }

    public void removeTid() {
        tidTreadLocal.remove();
    }

    /*public Span getNowSpan() {
        return nowSpanThreadLocal.get();
    }

    public void setNowSpan(Span span) {
        nowSpanThreadLocal.set(span);
    }

    public void removeNowSpan() {
        nowSpanThreadLocal.remove();
    }*/

}
